using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace SolarWinds.Shapes
{
    public class QuadShape : Shape
    {
        private VertexBuffer mVertexBuffer;
        private VertexDeclaration mVertexDeclaration;
        private BasicEffect mBasicEffect;

        private readonly string mTextureAsset;
        private Texture2D mTexture;

        private StateBlock mStateBlock;

        private readonly Vector3[] mVertices = {
                                                   new Vector3(-0.5f, 0, -0.5f), // bottom left
                                                   new Vector3(-0.5f, 0,  0.5f), // top left
                                                   new Vector3( 0.5f, 0, -0.5f), // bottom right
                                                   new Vector3( 0.5f, 0,  0.5f) // top right
                                               };

        public QuadShape(Game game, string textureAsset)
            : base(game)
        {
            mTextureAsset = textureAsset;
        }

        protected override void LoadContent()
        {
            GraphicsDevice device = Game.GraphicsDevice;

            mBasicEffect = new BasicEffect(device, null);
            //mBasicEffect.EnableDefaultLighting();
            mTexture = Game.Content.Load<Texture2D>(@"Textures\" + mTextureAsset);
            mStateBlock = new StateBlock(device);

            var vertexData = new VertexPositionTexture[4];

            vertexData[0].Position = mVertices[0];
            vertexData[1].Position = mVertices[1];
            vertexData[2].Position = mVertices[2];
            vertexData[3].Position = mVertices[3];

            vertexData[0].TextureCoordinate = new Vector2(0, 0);
            vertexData[1].TextureCoordinate = new Vector2(0, 1);
            vertexData[2].TextureCoordinate = new Vector2(1, 0);
            vertexData[3].TextureCoordinate = new Vector2(1, 1);

            mVertexBuffer = new DynamicVertexBuffer(device, typeof(VertexPositionTexture), 4, BufferUsage.WriteOnly);
            mVertexBuffer.SetData(vertexData);

            mVertexDeclaration = new VertexDeclaration(device, VertexPositionTexture.VertexElements);
        }

        public override void  Draw(GameTime gameTime)
        {
 	        base.Draw(gameTime);
 
            GraphicsDevice device = Game.GraphicsDevice;

            mStateBlock.Capture();

            device.Vertices[0].SetSource(mVertexBuffer, 0, VertexPositionTexture.SizeInBytes);
            device.VertexDeclaration = mVertexDeclaration;

            mBasicEffect.World = World;
            mBasicEffect.View = View;
            mBasicEffect.Projection = Projection;
            mBasicEffect.DiffuseColor = Color.CornflowerBlue.ToVector3();
            mBasicEffect.Texture = mTexture;
            mBasicEffect.TextureEnabled = true;
            mBasicEffect.CommitChanges();

            device.RenderState.AlphaBlendEnable = true;
            device.RenderState.SourceBlend = Blend.SourceAlpha;
            device.RenderState.DestinationBlend = Blend.InverseSourceAlpha;
            device.RenderState.DepthBufferWriteEnable = false;
            device.RenderState.CullMode = CullMode.None; 

            mBasicEffect.Begin();
            foreach (EffectPass pass in mBasicEffect.CurrentTechnique.Passes)
            {
                pass.Begin();
                device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2);
                pass.End();
            }
            mBasicEffect.End();

            mStateBlock.Apply();
        }

        protected override BoundingSphere UpdateBoundingSphere()
        {
            // better solution? BoundingSphere.CreateFromPoints(mVertices);
            return new BoundingSphere(Vector3.Zero, (Vector2.One * 0.5f).Length());
        }

        protected override BoundingBox UpdateBoundingBox()
        {
            // better solution? BoundingBox.CreateFromPoints(mVertices);
            return new BoundingBox(new Vector3(-0.5f, -0.5f, -float.Epsilon), new Vector3(0.5f, 0.5f, float.Epsilon));
        }
    }
}